package ranab.unit;


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.border.*;
import ranab.gui.GuiUtils;

/**
 * The unit converter user interface.
 *
 * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
 */
public 
class UnitConverter extends JFrame
                    implements ActionListener, 
                               TreeSelectionListener {

    private final static String SPLASH_IMG = "ranab/unit/unit.gif";
    private final static String ARROW_IMG  = "ranab/unit/bottom.gif";
    private final static String APP_NAME   = "Unit Converter";
    
    private BaseUnit[] mUnits;
    private BaseUnit   mSelUnit;
    
    private JTextField  mHeaderTxt;
    private JSplitPane  mSplitPane;
    private JTree       mTree;
    private JComboBox   mFromCombo;
    private JComboBox   mToCombo;
    private JTextField  mFromText;
    private JTextField  mToText;
    private JButton     mCalculateBtn;
    private UnitConverter mSelf;
    
    
    /**
     * constructor
     */
    public UnitConverter() {

        mSelf = this;
        
        // display splash window
        JWindow splashWin = GuiUtils.createSplashWindow(SPLASH_IMG);
        if (splashWin != null) {
            splashWin.setVisible(true);
        }
        
        // set unit array
        mUnits = new BaseUnit[] {
          new AreaUnit(),
          new DistanceUnit(),  
          new EnergyUnit(),
          new ForceUnit(),
          new PowerUnit(),  
          new PressureUnit(),
          new TemperatureUnit(),
          new VolumeUnit(),    
          new WeightUnit()
        };
        
        // create the main window
        createMainWindow();
        
        // remove the splash window
        if (splashWin != null) {
            splashWin.setVisible(false);
        }
        setVisible(true);
    }

    /**
     * create the main window
     */
    private void createMainWindow() {
        addSplitPane();
        setTitle(APP_NAME);
        setSize(new Dimension(520, 300));
        GuiUtils.setLocation(this);
    }

    /**
     * add split pane
     */
    private void addSplitPane() {
        mSplitPane = new JSplitPane();
        mSplitPane.setDividerSize(2);
        addLeftPane();
        addRightPane();
        getContentPane().add(mSplitPane);
    }

    /**
     * add the left pane
     */
    private void addLeftPane() {
        mTree = new JTree(mUnits);
        mTree.setEditable(false);
        mTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        mTree.addTreeSelectionListener(this);
        //mTree.putClientProperty("JTree.lineStyle", "Angled");
        
        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
        renderer.setLeafIcon(null);
        renderer.setOpenIcon(null);
        renderer.setClosedIcon(null);
        mTree.setCellRenderer(renderer);
        
        JScrollPane custPane = new JScrollPane(mTree, 
                                               JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                                               JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        mSplitPane.setLeftComponent(custPane);
        mSplitPane.setDividerLocation(120);
    }

    /** 
     * add the right pane
     */ 
    private void addRightPane() {
        JPanel rightPane = new JPanel();
        rightPane.setBorder(BorderFactory.createEtchedBorder());
        
        GridBagLayout gridbag = new GridBagLayout();
        GridBagConstraints c = new GridBagConstraints();
        rightPane.setLayout(gridbag);

        c.fill = GridBagConstraints.HORIZONTAL; 
        c.gridheight = 1;
        c.gridwidth = 1;
        c.insets.bottom = 3;
        c.insets.top = 3;
        c.insets.left = 2;
        c.insets.right =2;
        
        mHeaderTxt = new JTextField(APP_NAME);
        mHeaderTxt.setHorizontalAlignment(JLabel.CENTER);
        mHeaderTxt.setForeground(Color.black);
        mHeaderTxt.setFont(new Font(null, Font.BOLD, 14));
        mHeaderTxt.setBorder(BorderFactory.createEtchedBorder());
        mHeaderTxt.setEditable(false);
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 2;
        rightPane.add(mHeaderTxt, c);
        c.gridwidth = 1;
        
        JLabel fromLab = new JLabel("From");
        fromLab.setForeground(Color.black);
        c.gridx = 0;
        c.gridy = 1;
        rightPane.add(fromLab, c);
        
        JLabel fromUnitLab = new JLabel("Unit"); 
        fromUnitLab.setForeground(Color.black);
        c.gridx = 1;
        c.gridy = 1;
        rightPane.add(fromUnitLab, c);

        mFromText = new JTextField();
        mFromText.setColumns(12);
        c.gridx = 0;
        c.gridy = 2;
        rightPane.add(mFromText, c);
        
        mFromCombo = new JComboBox();
        c.gridx = 1;
        c.gridy = 2;
        rightPane.add(mFromCombo, c);
        
        JPanel btnPane = new JPanel();
        btnPane.setLayout(new FlowLayout(FlowLayout.CENTER));
        JButton calcBtn = null;
        ImageIcon btnImg = GuiUtils.createImageIcon(ARROW_IMG);
        if(btnImg != null) {
            calcBtn = new JButton(btnImg);
        }
        else {
            calcBtn = new JButton("Convert");
        }
        calcBtn.addActionListener(this);
        btnPane.add(calcBtn);
        c.gridx = 0;
        c.gridy = 3;
        c.gridwidth = 2;
        rightPane.add(btnPane, c);
        c.gridwidth = 1;
        
        JLabel toLab = new JLabel("To");
        toLab.setForeground(Color.black);
        c.gridx = 0;
        c.gridy = 4;
        rightPane.add(toLab, c);
        
        JLabel toUnitLab = new JLabel("Unit"); 
        toUnitLab.setForeground(Color.black);
        c.gridx = 1;
        c.gridy = 4;
        rightPane.add(toUnitLab, c);

        mToText = new JTextField();
        mToText.setColumns(12);
        c.gridx = 0;
        c.gridy = 5;
        rightPane.add(mToText, c);
        
        mToCombo = new JComboBox();
        c.gridx = 1;
        c.gridy = 5;
        rightPane.add(mToCombo, c);
        
        JScrollPane scrollpane = new JScrollPane(rightPane,
                                                 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                                                 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        mSplitPane.setRightComponent(scrollpane);   
    }


    /*
     * Handle window closing event.
     */ 
    protected void processWindowEvent(WindowEvent e) {
        int id = e.getID();
        if (id == WindowEvent.WINDOW_CLOSING) {
            if ( !GuiUtils.getConfirmation(this, "Do you really want to exit?") ) {
                return;
            }
            super.processWindowEvent(e);
            terminate();
        } 
        else {
            super.processWindowEvent(e);
        }    
    }
     
    /**
     * Calculate button handler
     */
    public void actionPerformed(ActionEvent evt) {
        if(mSelUnit == null) {
            GuiUtils.showErrorMessage(this,  "Please select an unit type from left pane");
            return;
        }
        
        try {
            mToText.setText("");
            int fromIndex = mFromCombo.getSelectedIndex();
            int toIndex = mToCombo.getSelectedIndex();
            mToText.setText(mSelUnit.convertUnit(mFromText.getText(), fromIndex, toIndex));
        }
        catch(UnitException ex) {
           GuiUtils.showErrorMessage(this,  ex.getMessage()); 
        }
    }  
     
    /**
     * Tree selection listener. Load <code>MyUnit</code> object.
     */
    public void valueChanged(TreeSelectionEvent evt) {
      TreePath tp = mTree.getSelectionPath();
      DefaultMutableTreeNode selNode = (DefaultMutableTreeNode)tp.getLastPathComponent();
      mSelUnit = (BaseUnit)selNode.getUserObject();
      
      // populate combo boxes
      String[] allUnits = mSelUnit.getAllUnits();
      mFromCombo.removeAllItems();
      mToCombo.removeAllItems();
      for(int i=0; i<allUnits.length; i++) {
        mFromCombo.addItem(allUnits[i]);
        mToCombo.addItem(allUnits[i]);
      }
      
      // change header text
      mHeaderTxt.setText(APP_NAME + " - " + mSelUnit.toString());
      mFromText.setText("");
      mToText.setText("");
    } 
     
    
    /**
     * termitate application
     */
    private void terminate() {
        setVisible(false);
        dispose();
        System.exit(0);
    }


    /** 
     * program starting point
     */
    public static void main(String args[]) {
        UnitConverter pc = new UnitConverter();
    }   
}